#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_freertos_hooks.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include"driver/gpio.h"
#include"key.h"
#include"lvgl_begin.h"
#include"iic_aht10.h"
#include"ina226.h"
#include"timer_soc_test.h"
/* Littlevgl specific */
#ifdef LV_LVGL_H_INCLUDE_SIMPLE
#include "lvgl.h"
#else
#include "lvgl.h"
#endif
//#include "lvgl/src/lv_core/lv_obj.h"
#include "lvgl_helpers.h"

#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
    #if defined CONFIG_LV_USE_DEMO_WIDGETS
        #include "lv_examples/src/lv_demo_widgets/lv_demo_widgets.h"
    #elif defined CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER
        #include "lv_examples/src/lv_demo_keypad_encoder/lv_demo_keypad_encoder.h"
    #elif defined CONFIG_LV_USE_DEMO_BENCHMARK
        #include "lv_examples/src/lv_demo_benchmark/lv_demo_benchmark.h"
    #elif defined CONFIG_LV_USE_DEMO_STRESS
        #include "lv_examples/src/lv_demo_stress/lv_demo_stress.h"
    #else
        #error "No demo application selected."
    #endif
#endif

/*********************
 *      DEFINES
 *********************/
#define TAG "demo"
#define LV_TICK_PERIOD_MS 1
#define BTN_LENGTH  60
#define BTN_WIDTH   30
#define key_switch 0 //打印按键key值开关
/**********************
 *  GLOBAL VARIABLE
 **********************/
lv_indev_t * indev_keypad;
SemaphoreHandle_t xGuiSemaphore;
uint8_t right_key_flag = 0;
uint8_t up_key_flag = 0;
uint8_t enter_key_flag = 0;
uint8_t temp_flag = 0;//temp界面标志位，为1则进入temp页面
uint8_t cun_flag = 0;
uint8_t vol_flag = 0;
uint8_t soc_flag = 0;
lv_obj_t *scr;
lv_obj_t* vol_btn;
lv_obj_t *temp_btn;
lv_obj_t *soc_btn;
lv_obj_t *current_btn;
lv_obj_t *temp_label;
lv_obj_t *current_label;
lv_obj_t *vol_label;
lv_obj_t *soc_label;

lv_obj_t *temp_cont = NULL;
lv_obj_t *vol_cont = NULL;
lv_obj_t *cun_cont = NULL ;
lv_obj_t *soc_cont = NULL;
lv_obj_t *gui_cont = NULL;
extern uint16_t temp,humi;//aht10
//ina226
extern uint16_t ID,config;
extern xQueueHandle busvol_Gui_queue;
extern xQueueHandle current_queue;
/*timer_soc_test文件内的soc消息队列*/
extern xQueueHandle soc_queue;
//代码写在这里时
//QueueHandle_t xQueue;
//xQueue = xQueueCreate( 1, sizeof(char *) );
//编译出现错误error: type defaults to 'int' in declaration of 'xQueue' [-Werror=implicit-int]
//原因是xQueue = xQueueCreate( 1, sizeof(char *) );需要放在函数内。
//但是当把它放在函数内，aht任务和gui任务分别创建发送和接收队列会出现屏幕一直闪烁。所以还是使用全局变量在两个任务之间传递参数。

 void guiTask(void *pvParameter) {

    (void) pvParameter;
    xGuiSemaphore = xSemaphoreCreateMutex();
    lv_init();
    /* Initialize SPI or I2C bus used by the drivers 
    使用预编译选择显示引脚、触摸驱动
    引脚由sdkconfig配置文件决定,如果用的SPI触摸屏，配置文件内SHARED_SPI_BUS = 1；
    如果使用非触摸屏，配置文件内CONFIG_LV_TFT_DISPLAY_PROTOCOL_SPI = 1
    */
    lvgl_driver_init();
    //DISP_BUF_SIZE的大小默认是水平像素大小的40倍
    lv_color_t* buf1 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t)*2, MALLOC_CAP_DMA);
    assert(buf1 != NULL);

    /* Use double buffered when not working with monochrome displays */
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
    lv_color_t* buf2 = heap_caps_malloc(DISP_BUF_SIZE * sizeof(lv_color_t)*2, MALLOC_CAP_DMA);
    assert(buf2 != NULL);
#else
    static lv_color_t *buf2 = NULL;
#endif

    static lv_disp_buf_t disp_buf;

    uint32_t size_in_px = DISP_BUF_SIZE;

#if defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_IL3820         \
    || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_JD79653A    \
    || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_UC8151D     \
    || defined CONFIG_LV_TFT_DISPLAY_CONTROLLER_SSD1306

    /* Actual size in pixels, not bytes. */
    size_in_px *= 8;
#endif

    /* Initialize the working buffer depending on the selected display.
     * NOTE: buf2 == NULL when using monochrome displays. */
    lv_disp_buf_init(&disp_buf, buf1, buf2, size_in_px);//无效，因为menuconfig未设定

    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);//初始化屏幕尺寸、旋转角度、屏幕显示的缓存空间、颜色格式（如黑白、RGB565等）
    /*继续添加真实的屏幕大小、驱动芯片类型*/
    disp_drv.hor_res=160;
    disp_drv.ver_res=80;

    
    disp_drv.flush_cb = disp_driver_flush;//设置屏幕驱动芯片类型

    /* When using a monochrome display we need to register the callbacks:
     * - rounder_cb
     * - set_px_cb */
#ifdef CONFIG_LV_TFT_DISPLAY_MONOCHROME
    disp_drv.rounder_cb = disp_driver_rounder;
    disp_drv.set_px_cb = disp_driver_set_px;
#endif

    disp_drv.buffer = &disp_buf;
    //
    lv_disp_drv_register(&disp_drv);//设置屏幕背景色、背景图片、透明度等
    //正点原子8.2版本例程将lv_disp_drv_init、lv_disp_drv_register放在一个函数lv_port_disp_init
    /* Register an input device when enabled on the menuconfig */
#if CONFIG_LV_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.read_cb = touch_driver_read;
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    lv_indev_drv_register(&indev_drv);
#endif

    /* Create and start a periodic timer interrupt to call lv_tick_inc */
    const esp_timer_create_args_t periodic_timer_args = {
        .callback = &lv_tick_task,
        .name = "periodic_gui"
    };
    esp_timer_handle_t periodic_timer;
    ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));//
    ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, LV_TICK_PERIOD_MS * 1000));

    /* Create the demo application */
    //create_demo_application();
    lv_port_indev_init();//输入设备初始化，触摸、按键、编码器等
    gui_begin ();
    while (1) {
        /* Delay 1 tick (assumes FreeRTOS tick is 10ms */
        vTaskDelay(pdMS_TO_TICKS(20));//*这是RTOS的tick，不同于裸机运行LVGL
        /* Try to take the semaphore, call lvgl related function on success */
        if (pdTRUE == xSemaphoreTake(xGuiSemaphore, portMAX_DELAY)) {
            lv_task_handler();
            xSemaphoreGive(xGuiSemaphore);
       }
    }

    /* A task should NEVER return */
    free(buf1);
#ifndef CONFIG_LV_TFT_DISPLAY_MONOCHROME
    free(buf2);
#endif
    vTaskDelete(NULL);
}

void create_demo_application(void)
{
    /* When using a monochrome display we only show "Hello World" centered on the
     * screen */
 #if defined CONFIG_LV_TFT_DISPLAY_MONOCHROME
 

    /* use a pretty small demo for monochrome displays */
    /* Get the current screen  */
    lv_obj_t * scr = lv_disp_get_scr_act(NULL);

    /*Create a Label on the currently active screen*/
    lv_obj_t * label1 =  lv_label_create(scr, NULL);

    /*Modify the Label's text*/
    lv_label_set_text(label1, "Hello\nworld");

    /* Align the Label to the center
     * NULL means align on parent (which is the screen now)
     * 0, 0 at the end means an x, y offset after alignment*/
    lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0);
#else
    /* Otherwise we show the selected demo */

    #if defined CONFIG_LV_USE_DEMO_WIDGETS
        lv_demo_widgets();
    #elif defined CONFIG_LV_USE_DEMO_KEYPAD_AND_ENCODER
        lv_demo_keypad_encoder();
    #elif defined CONFIG_LV_USE_DEMO_BENCHMARK
        lv_demo_benchmark();
    #elif defined CONFIG_LV_USE_DEMO_STRESS
        lv_demo_stress();
    #else
        #error "No demo application selected."
    #endif
#endif
}



 void lv_tick_task(void *arg) {
    (void) arg;

    lv_tick_inc(LV_TICK_PERIOD_MS);
}
//参考 https://blog.csdn.net/HC_huangcheng/article/details/110001613
//可参考韦东山输入设备接口章节 http://lvgl.100ask.net/7.11/documentation/02_porting/04_indev.html
//移植中添加keypad相关的初始化以及正确填充 indev_drv 这个结构体。
bool keypad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)
{
    static uint32_t last_key = 100; //!初始值不要和自带的key值一样，如LV_KEY_NEXT

    /*Get whether the a key is pressed and save the pressed key*/
    uint32_t act_key = keypad_get_key();//上键返回3，右键返回4，中建返回5
    if (key_switch){
        printf("act_key = %d\n",act_key);
    }
    if(act_key != 0) {
        data->state = LV_INDEV_STATE_PR;
        /*Translate the keys to LVGL control characters according to your key definitions*/
        switch(act_key) {
            case 1:
                act_key = LV_KEY_NEXT;//转化为LVGL自己的key值
                break;
            case 2:
                act_key = LV_KEY_PREV;
                break;
            case 3:
                act_key = LV_KEY_UP;
                up_key_flag++;
                break;
            case 4:
                act_key = LV_KEY_RIGHT;
                right_key_flag++;
                break;
            case 5:
                act_key = LV_KEY_ENTER;
                enter_key_flag++;
                break;
            case 6:
            act_key = LV_KEY_HOME;
                break;
            default :
                break;
        }

        last_key = act_key;
    } else {
        data->state = LV_INDEV_STATE_REL;
    }

    data->key = last_key;//*将key值传给“输入设备数据结构体”，详情见下面接口初始化函数内的read_cb

    /*Return `false` because we are not buffering and no more data to read*/
    return false;
}
/*******************************************************************************
* 函数名         : void lv_port_indev_init(void)
* 函数功能		  : 按键接口初始化
* 输入           : 无
* 输出         	 : 无
PS:LVGL原始的port文件内的lv_port_indev_init函数包括触摸屏、鼠标、编码器、键盘等接口预编译语句，
虽然修改预编译就可以选择键盘输入，但是代码有点多，所以我只复制了键盘初始化的程序
*******************************************************************************/
void lv_port_indev_init(void)
{
    key_init();	
    /*Register a keypad input device*/
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);
    indev_drv.type = LV_INDEV_TYPE_KEYPAD;
    //*read_cb：输入设备数据的函数指针
    indev_drv.read_cb = keypad_read;//*执行keypad_read的频率应该取决于tick时钟，我设置的是1ms
    indev_keypad = lv_indev_drv_register(&indev_drv);
}


/*Get the currently being pressed key.  0 if no key is pressed
正确使用return，不要添加else if
*/
 uint32_t keypad_get_key(void)
{
if( gpio_get_level(center_key) == 0)
    {   ////确认键不需要延时，检测到很多按键也只会进入界面一次
        //!需要延时，否则多次删除容器导致LVGL卡住
        vTaskDelay(pdMS_TO_TICKS(100));
        if(gpio_get_level(center_key) == 0)
            {
            printf("center_key = %d\n",gpio_get_level(center_key));
            return 5;	
            }
        else
            return 0;       
    }
if(gpio_get_level(up_key) == 0)
    {
        vTaskDelay(pdMS_TO_TICKS(100));//合理的延时时间，否则跳转的画面非选择的画面
        if(gpio_get_level(up_key) == 0)
            return 3;   //和LV_KEY_LEFT对应
        else
            return 0; 
    }
    
if (gpio_get_level(right_key) == 0)
    {
        vTaskDelay(pdMS_TO_TICKS(100));//
        if(gpio_get_level(right_key) == 0)
            {
                printf("right_key = %d\n",gpio_get_level(right_key));
                return 4;
            }
        else
            return 0; 
    }
    return 0; 
}

/*******************************************************************************
* 函数名         : void event_callback(struct _lv_obj_t * obj, lv_event_t event)
* 函数功能		  : 按钮的事件回调函数
* 输入           : 
* 输出         	 : 无
*******************************************************************************/
 void event_callback(struct _lv_obj_t * obj, lv_event_t event)
{
	if (event == LV_EVENT_KEY){
		const uint32_t *key = lv_event_get_data();
		if (*key == LV_KEY_ENTER){ //确认键按下
            if (enter_key_flag%2)
            {
                switch ((up_key_flag)%4) //四个按钮，四次一个循环
                    {
                        case 0: //选择temp按钮
                            temp_flag = 1;
                            //lv_obj_del(gui_cont);
                            //!一个控件占的空间较少，似乎创建几百次也没问题，所以这里没有释放之前主界面的空间
                            temp_page();
                            break;
                        case 1: //选择cun按钮
                            cun_flag = 1;
                            //lv_obj_del(gui_cont);
                            current_page();
                            break;
                        case 2: //选择vol按钮
                            vol_flag = 1;
                            //lv_obj_del(gui_cont);
                            vol_page();
                            break;
                        case 3: //选择soc按钮
                            soc_flag = 1;
                            //lv_obj_del(gui_cont);
                            soc_page();
                            break;
                        default:
                            break;
                    }
            }
            else 
            {
                switch ((up_key_flag)%4) //四个按钮，四次一个循环
                    {
                        case 0: //选择temp按钮
                            temp_flag = 1;
                            temp_page();
                            break;
                        case 1: //选择cun按钮
                            cun_flag = 1;
                            current_page();
                            break;
                        case 2: //选择vol按钮
                            vol_flag = 1;
                            vol_page();
                            break;
                        case 3: //选择soc按钮
                            soc_flag = 1;
                            soc_page();
                            break;
                        default:
                            break;
                    }
            }
                
		}else if(*key == LV_KEY_UP){
            switch ((up_key_flag)%4)
            {
            case 0:
                lv_label_set_recolor(temp_label, true);//使能重绘色
                lv_label_set_text(temp_label, "#00ff00 TEM #");
                lv_label_set_text(current_label, "CUN");
                lv_label_set_text(vol_label, "VOL");
                lv_label_set_text(soc_label, "SOC");
                break;
            case 1:
                lv_label_set_recolor(current_label, true);//使能重绘色
                lv_label_set_text(current_label, "#00FF00 CUN #");
                lv_label_set_text(temp_label, "TEM");
                lv_label_set_text(vol_label, "VOL");
                lv_label_set_text(soc_label, "SOC");
                break;
            case 2:
                lv_label_set_recolor(vol_label, true);//使能重绘色
                lv_label_set_text(vol_label, "#00FF00 VOL #");
                lv_label_set_text(current_label, "CUN");
                lv_label_set_text(temp_label, "TEM");
                lv_label_set_text(soc_label, "SOC");
                break;
            case 3:
                lv_label_set_recolor(soc_label, true);//使能重绘色
                lv_label_set_text(soc_label, "#00FF00 SOC #");
                lv_label_set_text(vol_label, "VOL");
                lv_label_set_text(current_label, "CUN");
                lv_label_set_text(temp_label, "TEM");
                break;
            default:
                break;
            }
            printf("*key = %d,left_key_flag = %d\n",*key,up_key_flag); 
            //其实是判断按下的是否是左键，如果按键次数太多，gui_begin生成太多空间，内存会消耗完，           
		}else if(*key == LV_KEY_RIGHT){
            if (right_key_flag%2)
                {
                    switch ((up_key_flag)%4)
                    {
                        case 0:
                            lv_obj_del(temp_btn);//!由于初始时未初始化temp容器，在home界面按下左键会卡住，因此只删除btn
                            //!如果连按左键多次，第一次已经删掉了容器，第二次再删掉未存在的容器则会卡住
                            //!每次返回主界面会再次创建控件，次数多了，占的空间太多，LVGL会卡住， 所以使用gui_home，
                            //!每次使用gui_begin已经创建完的容器，而不每次都新建容器，这样会保证左键连按70次，stack不溢出  
                            gui_home();
                            break;
                        case 1:
                            lv_obj_del(current_btn);
                            gui_home();
                            break;                
                        case 2:
                            lv_obj_del(vol_btn);
                            gui_home();
                            break;
                        case 3:
                            lv_obj_del(soc_btn);
                            gui_home();////这样返回主界面，似乎消耗太多空间，导致LVGL卡住
                            break;    
                        default:
                            break;                                        
                    }
                }      
            else{
                gui_begin();
            }
        // printf("*key = %d,right_key_flag = %d\n",*key,right_key_flag);
     }
    }
}

/// @brief 
/// @param  
void gui_begin (void)
{	
    
    gui_cont = lv_obj_create(lv_scr_act(),NULL);
    lv_obj_set_size(gui_cont, 168, 88);
    lv_obj_set_pos(gui_cont,-4,-1);
 
    // lv_obj_set_style_local_bg_opa(gui_cont, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_100);//设置颜色覆盖度100%，数值越低，颜色越透。
 
    // lv_obj_set_style_local_bg_color(gui_cont, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xa7,0x00,0x2f));//顺序为蓝、红、绿
    static lv_style_t style1;
    lv_style_set_bg_color(&style1,LV_STATE_DEFAULT, lv_color_hex(0xBA55D3));
    lv_obj_add_style(gui_cont, LV_OBJ_PART_MAIN, &style1);
     //btn风格
    static lv_style_t style_shadow;
      lv_style_init(&style_shadow);
     lv_style_set_border_opa(&style_shadow, LV_STATE_DEFAULT, 100);
     lv_style_set_shadow_spread(&style_shadow, LV_STATE_DEFAULT, 3);
     lv_style_set_shadow_color(&style_shadow, LV_STATE_DEFAULT, lv_color_hex(0XFFFF00));

    //温度显示
    temp_btn= lv_btn_create(gui_cont,NULL);
    lv_obj_set_size(temp_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_set_pos(temp_btn,5,5);
    //lv_obj_set_style_local_bg_opa(temp_btn, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_100);//设置颜色覆盖度100%，数值越低，颜色越透。

    //lv_obj_set_style_local_bg_color(temp_btn, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0XFFFF00));
    lv_obj_set_event_cb(temp_btn,event_callback);
    temp_label = lv_label_create(temp_btn,NULL);
    lv_label_set_text(temp_label,"TEM");
    //电压显示
    vol_btn = lv_btn_create(gui_cont,NULL);
    lv_obj_set_pos(vol_btn,5,42);
    lv_obj_set_size(vol_btn,BTN_LENGTH,BTN_WIDTH);
    vol_label = lv_label_create(vol_btn,NULL);
    lv_label_set_text(vol_label,"VOL");
    //电流显示
    current_btn = lv_btn_create(gui_cont,NULL);
    lv_obj_set_pos(current_btn,70,5);
    lv_obj_set_size(current_btn,BTN_LENGTH,BTN_WIDTH);
    current_label = lv_label_create(current_btn,NULL);
    lv_label_set_text(current_label,"CUN");
    //容量显示
    soc_btn = lv_btn_create(gui_cont,NULL);
    lv_obj_set_pos(soc_btn,70,42);
    lv_obj_set_size(soc_btn,BTN_LENGTH,BTN_WIDTH);
    soc_label = lv_label_create(soc_btn,NULL);
    lv_label_set_text(soc_label,"SOC");

    lv_group_t *group = lv_group_create();
	lv_indev_set_group(indev_keypad, group);
    lv_group_add_obj(group ,temp_btn);
}

/// @brief 初始主界面
/// @param  
void gui_home (void)
{	
    temp_btn= lv_btn_create(gui_cont,NULL);
    lv_obj_set_size(temp_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_set_pos(temp_btn,5,5);
    lv_obj_set_event_cb(temp_btn,event_callback);
    temp_label = lv_label_create(temp_btn,NULL);
    lv_label_set_text(temp_label,"TEM");
    //电压显示
    vol_btn= lv_btn_create(gui_cont,NULL);
    lv_obj_set_pos(vol_btn,5,42);
    lv_obj_set_size(vol_btn,BTN_LENGTH,BTN_WIDTH);
    vol_label = lv_label_create(vol_btn,NULL);
    lv_label_set_text(vol_label,"VOL");
    //电流显示
    current_btn= lv_btn_create(gui_cont,NULL);
    lv_obj_set_pos(current_btn,70,5);
    lv_obj_set_size(current_btn,BTN_LENGTH,BTN_WIDTH);
    current_label = lv_label_create(current_btn,NULL);
    lv_label_set_text(current_label,"CUN");
    //容量显示
    soc_btn= lv_btn_create(gui_cont,NULL);
    lv_obj_set_pos(soc_btn,70,42);
    lv_obj_set_size(soc_btn,BTN_LENGTH,BTN_WIDTH);
    soc_label = lv_label_create(soc_btn,NULL);
    lv_label_set_text(soc_label,"SOC");
   
    lv_group_t *group = lv_group_create();
	lv_indev_set_group(indev_keypad, group);
    lv_group_add_obj(group ,temp_btn);


}

/// @brief 温度显示界面
void temp_page()
{
    temp_cont = lv_cont_create(lv_scr_act(), NULL);
    lv_obj_set_size(temp_cont, 160, 80);
    LV_IMG_DECLARE(girl2);
    lv_obj_t * img1 = lv_img_create(temp_cont, NULL);
    lv_img_set_src(img1, &girl2);
    lv_img_set_angle(img1, 0);
    lv_obj_set_pos(img1,0,0);
    lv_img_set_antialias(img1, true);
    lv_cont_set_fit(temp_cont, LV_FIT_NONE);
    //第一块温度显示
    lv_obj_t *temp1_btn;
    temp1_btn= lv_btn_create(img1,NULL);
    lv_obj_set_size(temp1_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_set_pos(temp1_btn,5,5);
    lv_obj_set_event_cb(temp1_btn,event_callback);
    lv_obj_t *temp1_label;
    temp1_label = lv_label_create(temp1_btn,NULL);
    lv_label_set_text_fmt(temp1_label, "%d", temp/10);
    //第二块温度显示
    lv_obj_t *temp2_btn;
    temp2_btn = lv_btn_create(img1,NULL);
    lv_obj_set_pos(temp2_btn,5,42);
    lv_obj_set_size(temp2_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_t *temp2_label;
    temp2_label = lv_label_create(temp2_btn,NULL);
   lv_label_set_text(temp2_label,"TEMP2");
}

/// @brief //电压显示界面
void vol_page()
{
    vol_cont = lv_cont_create(lv_scr_act(), NULL);
    lv_obj_set_size(vol_cont,160,80);

    lv_obj_t *vol1_btn;
    vol1_btn = lv_btn_create(vol_cont,NULL);
    lv_obj_set_pos(vol1_btn,5,5);
    lv_obj_set_size(vol1_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_t *vol1_label;
    vol1_label = lv_label_create(vol1_btn,NULL);
   //INA226 AD
    lv_label_set_text_fmt(vol1_label,"%X",config);//使用%f打印，如果使用%d则会为0，因为浮点型和整型的存储格式不同，所以要按浮点型打印出来。
    lv_obj_t *vol2_btn;
    vol2_btn = lv_btn_create(vol_cont,NULL);
    lv_obj_set_pos(vol2_btn,5,42);
    lv_obj_set_size(vol2_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_t *vol2_label;
    vol2_label = lv_label_create(vol2_btn,NULL);
    float ina226_busvol;
    //使用消息队列
    xQueueReceive(busvol_Gui_queue, &ina226_busvol, 0);//等待时间为0，消息队列为空就立即返回
    lv_label_set_text_fmt(vol2_label,"%.1f",ina226_busvol);//单位为mv
}

/// @brief 电流显示界面
void current_page()
{
    cun_cont = lv_cont_create(lv_scr_act(), NULL);
    lv_obj_set_size(cun_cont,160,80);
    lv_obj_t *cun_btn;
    cun_btn = lv_btn_create(cun_cont,NULL);
    lv_obj_set_pos(cun_btn,5,5);
    lv_obj_set_size(cun_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_t *cun1_label;
    cun1_label = lv_label_create(cun_btn,NULL);
    float current;
    xQueueReceive(current_queue, &current, 0);
    lv_label_set_text_fmt(cun1_label,"%4.0f",current);//单位为ma
}

void soc_page()
{
    soc_cont = lv_cont_create(lv_scr_act(), NULL);
    lv_obj_set_size(soc_cont,160,80);
    lv_obj_t *soc1_btn;
    soc1_btn = lv_btn_create(soc_cont,NULL);
    lv_obj_set_pos(soc1_btn,5,5);
    lv_obj_set_size(soc1_btn,BTN_LENGTH,BTN_WIDTH);
    lv_obj_t *soc1_label;
    soc1_label = lv_label_create(soc1_btn,NULL);
    float soc=0;
    xQueueReceive(soc_queue, &soc, 0);//等待时间为0，消息队列为空就立即返回
    lv_label_set_text_fmt(soc1_label,"%.2f",soc);//current = Shunt_vol/shunt_resistance,板载的采样电阻为0.1欧
}